package cn.xmall.caches.impl;

import cn.xmall.caches.OrderCache;
import net.sf.jsqlparser.expression.DateTimeLiteralExpression;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.StringRedisConnection;
import org.springframework.data.redis.core.*;
import org.springframework.stereotype.Repository;
import org.springframework.util.Assert;

/**
 * Created by MoTaiXian on 2017/7/20.
 */
@Repository
public class OrderCacheImpl implements OrderCache {

    private String RandNumPoolKey="RandNumPool:";

    private String OrderItemSerialNumKey="OrderItemSerialKey:";

    private long NumOfDigits=5;

    @Autowired
    RedisTemplate<String,Long> redisTemplate;

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    private void FillRandNumPool(){
        long min=0;
        long max=(long)Math.pow((double) 10,(double) NumOfDigits);

        stringRedisTemplate.execute(new RedisCallback<Long>() {
            @Override
            public Long doInRedis(RedisConnection redisConnection) throws DataAccessException {
                StringRedisConnection stringRedisConnection=(StringRedisConnection) redisConnection;
                stringRedisConnection.openPipeline();
                for(long i=min;i<max;i++){
                    stringRedisConnection.sAdd(RandNumPoolKey,String.valueOf(i));
                }

                stringRedisConnection.closePipeline();
                return null;
            }
        });
    }

    private String getRandNumFromPool(){
        BoundSetOperations<String,String> randPoolOp=stringRedisTemplate.boundSetOps(RandNumPoolKey);
        //1. 随机号池没有建立
        Assert.notNull(randPoolOp,"randPoolOp is null");

        String strNum=randPoolOp.pop();
        if(strNum==null){
            FillRandNumPool();
            strNum=randPoolOp.pop();
        }
        Long num=Long.valueOf(strNum);
        //2. 随机号池中没有号码
        return String.format("%0"+NumOfDigits+"d",num);
    }

    @Override
    public String generateUniqueOrderId(String prefix,String subfix) {
        String date_seg=new DateTime().plusYears(-2000).toString("yyMMddHHmm");
        String random=getRandNumFromPool();
        return prefix+date_seg+random+subfix;
    }

}
